package main

import (
	"fmt"
	"time"
)

//通道同步函数
func worker(done chan bool) {
	fmt.Println("working...")
	time.Sleep(time.Second)
	fmt.Println("done")

	done <- true
}

//当使用通道作为参数时，可以指定是否仅用于发送或接收值
func ping(ping chan<- string, msg string) {
	ping <- msg
}

//pong函数接受一个通道接收（pings）和第二个发送（pongs）
func pong(pings <-chan string, pongs chan<- string) {
	mesg := <-pings
	pongs <- mesg
}

func main() {

	// 通道是连接并发混合程序的管道
	// 可以从一个goroutine将值发送到通道中，并将这些值接收到另一个goroutine中
	msg := make(chan string)
	// 使用channel <- 语法将值发送到通道
	go func() { msg <- "ping" }()
	// <- channel语法接收从信道的值
	m := <-msg
	//默认情况下发送和接收阻塞，直到发送者和接收者都准备好
	//该能够在程序结束时等待"ping" 消息，而无需使用任何其他同步
	fmt.Println(m)

	//通道缓冲区可以有2个值
	messages := make(chan string, 2)
	messages <- "buffered"
	messages <- "channel"

	//不需要相应的并发接收,可以照常收到这两个值
	fmt.Println(<-messages)
	fmt.Println(<-messages)

	done := make(chan bool, 1)
	//同步执行goroutine
	go worker(done)
	//如果<- done从这个程序中删除了该行，程序会在worker开始之前退出
	//等到done有值结束程序
	<-done

	pings := make(chan string, 1)
	pongs := make(chan string, 1)

	ping(pings, "passed message")
	pong(pings, pongs)
	fmt.Println(<-pongs)
}
